import Cesium from '../Ces/Cesium'

class WeFontAltas {
  url
  fontFamily = '华为黑体'
  _loading
  _ready
  _readyPromise
  bold = true
  private _textDimensionsCache
  private _billboardTextureCache
  private textureAtlas
  private MissingT
  constructor(options) {
    this.url = options.url
    this._loading = false
    this._ready = false
    this._readyPromise = Cesium.defer()
  }

  get ready() {
    return this._ready
  }
  set ready(value) {
    this._ready = value
  }

  get readyPromise() {
    return this._readyPromise.promise
  }

  getFont(fontSize) {
    return `${this.bold ? 'bold ' : ''}${fontSize}px ${this.fontFamily}`
  }

  createLabelCollection(options) {
    return this.NewLabelCollection(options)
  }

  NewLabelCollection(options = {}) {
    const labelCollection = new Cesium.LabelCollection(options)
    this.install(labelCollection)
    const destroy = labelCollection.destroy
    labelCollection.destroy = () => {
      labelCollection._glyphBillboardCollection._textureAtlas = undefined
      return destroy.bind(labelCollection)()
    }
    return labelCollection
  }

  validCache(text) {
    let valid = true

    for (const element of text) {
      if(element === '\r\n' || element === '\n') continue
      const id = `["${element}","${this.fontFamily}","normal","700",2]`

      if (!this._billboardTextureCache.get(id)) {
        valid = false

        if (!Cesium.defined(this.MissingT)) {
          this.MissingT = {}
        }
        const missingT = this.MissingT

        if (!missingT[element]) {
          missingT[element] = id
          // console.info(`missing ${Object.keys(missingT)}`)
        }
        break
      }
    }

    return valid
  }

  ininitAtals(context) {
    if (this._loading) {
      return
    }
    this._loading = true

    const url = this.url
    const that = this

    Cesium.Resource.fetchJson(url)
      .then((json) => {
        const desc = json.desc || {}
        that.bold = desc.bold??true
        that.fontFamily = desc.fontFamily?? '华文黑体'
        const billboardTextureCache = JSON.parse(json._billboardTextureCache)
        const rectangles = JSON.parse(json._rectangles)
        this._textDimensionsCache = JSON.parse(json._textDimensionsCache)
        const image = new Image()

        image.src = json.url
        image.onload = () => {
          const texture = new Cesium.Texture({
            context,
            source: image,
            flipY: true,
          })
          const textureAtlas = new Cesium.TextureAtlas({
            context,
          })
          const borderPadding = textureAtlas._borderWidthInPixels
          textureAtlas._texturePacker = new Cesium.TexturePacker({
            height: image.height,
            width: image.width,
            borderPadding,
          })

          const _billboardTextureCache = new Map()

          Object.keys(billboardTextureCache).forEach((k) => {
            const { _index, _width, _height, _id, _loadState, dirty } = billboardTextureCache[k]
            const billboardTexture = new Cesium.BillboardTexture({})
            billboardTexture.dirty = dirty
            billboardTexture._index = _index
            billboardTexture._width = _width
            billboardTexture._height = _height
            billboardTexture._id = _id
            billboardTexture._loadState = _loadState
            _billboardTextureCache.set(k, billboardTexture)
            textureAtlas._indexById[k] = _index
          })
          textureAtlas._texture = texture
          for (let i = 0; i < rectangles.length; i++) {
            const { x, y, width, height } = rectangles[i]

            textureAtlas._rectangles[i] = new Cesium.BoundingRectangle(x, y, width, height)
            // textureAtlas._subRegions[i] = new Cesium.BoundingRectangle(x, y, width, height)
          }
          that._billboardTextureCache = _billboardTextureCache
          that.textureAtlas = textureAtlas
          that._loading = false
          that._ready = true

          that._readyPromise.resolve(that)
        }
      })
      .catch((e) => {
        console.error(e)
      })
  }

  install(labelCollection) {
    labelCollection._textDimensionsCache = this._textDimensionsCache
    labelCollection._glyphBillboardCollection._billboardTextureCache = this._billboardTextureCache
    labelCollection._glyphBillboardCollection._textureAtlas = this.textureAtlas
    labelCollection._glyphBillboardCollection._textureAtlasGUID =
      this.textureAtlas._textureAtlasGUID
  }

  destroy() {
    console.log(111)
    this.textureAtlas = this.textureAtlas && this.textureAtlas.destroy()

    return Cesium.destroyObject(this)
  }

  isDestroyed() {
    return false
  }
}

export default WeFontAltas
